package com.xc.sys.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Sets;
import com.xc.common.object.LayuiTableResponse;
import com.xc.common.object.PageInfo;
import com.xc.common.object.TreeObject;
import com.xc.common.tool.Helper;
import com.xc.db.tables.SysNavi;
import com.xc.db.tables.SysRoleNavi;
import com.xc.sys.entity.SysDictEntity;
import com.xc.sys.entity.SysNaviEntity;
import com.xc.sys.entity.SysUserEntity;
import com.xc.sys.service.SysDictService;
import com.xc.sys.service.SysNaviService;
import com.xc.sys.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.jooq.Condition;
import org.jooq.Record;
import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

@RestController
@CrossOrigin
@RequestMapping({ "/navi" })
public class SysNaviController {
	@Autowired
	private SysNaviService sysNaviService;
	@Autowired
	private SysUserService sysUserService;
	private SysNavi navi = SysNavi.SYS_NAVI.as("NAVI");
	private SysRoleNavi SYSROLENAVITB = SysRoleNavi.SYS_ROLE_NAVI.as("SYSROLENAVITB");
	@RequestMapping({ "/getLeftNaviList" })
	public LayuiTableResponse<JSONObject> getLeftNaviTree(Integer parentId, HttpServletRequest request) {
		List<JSONObject> data = new ArrayList<>();
		joinLeftTreeNode(parentId, data, null, request);
		LayuiTableResponse<JSONObject> ltr = new LayuiTableResponse<>();
		ltr.setData(data);
		return ltr;
	}

	private void joinLeftTreeNode(Integer parentId, List<JSONObject> data, JSONObject node, HttpServletRequest request) {
		SysUserEntity me = Helper.getMe(request);
		if(me==null){
			String createUserId = request.getParameter("createUserId");
			me = sysUserService.getEntityById(createUserId);
		}
		List<SysNaviEntity> result = null;
		Condition cond = DSL.or(navi.STATE.eq(5),navi.STATE.eq(7));
		if(parentId==null) {
			cond = cond.and(DSL.or(navi.PARENT_ID.isNull(),navi.PARENT_ID.isNull()));
		}else {
			cond = cond.and(navi.PARENT_ID.eq(parentId));
		}
		if(!me.getId().equals("1")) {
			String[] roleCodes = StringUtils.split(me.getRoleCode(),",");
			if(roleCodes!=null&&roleCodes.length>0) {
				
				cond = cond.and(navi.ID.in(DSL.select(SYSROLENAVITB.NAVI_ID).from(SYSROLENAVITB).where(SYSROLENAVITB.ROLE_CODE.in(roleCodes))));
			}else {
				cond = navi.ID.isNull();
			}
		}
		result = sysNaviService.select(cond, navi.ORDERNO.asc());
		JSONArray arr = null;
		if ((result.size() > 0) && (node != null)) {
			arr = new JSONArray();
		}
		for (SysNaviEntity r : result) {
			String id = r.getId();
			String name = r.getName();
			String icon = r.getIcon();
			String url = r.getUrl();
			JSONObject jobj = new JSONObject();
			jobj.put("name", id);
			jobj.put("title", name);
			jobj.put("icon", icon);
			jobj.put("state", r.getState());
			if (StringUtils.isNotEmpty(url)) {
				jobj.put("jump", url + "/id=" + id);
				jobj.put("url", url + "&naviid=" + id);
			}
			if (arr == null) {
				data.add(jobj);
			} else {
				arr.add(jobj);
			}
			joinLeftTreeNode(Integer.valueOf(id), data, jobj, request);
		}
		if (arr != null) {
			node.put("list", arr);
		}
	}

	/**
	 * 
	 * 作者：曾平 时间：2019年11月5日 下午3:08:58 功能：菜单管理
	 */
	@RequestMapping({ "/getNaviTree" })
	public List<TreeObject> getNaviTree(Integer pid, HttpServletRequest request) {
		List<TreeObject> list = new ArrayList<>();
		joinTreeNode(pid, list, null, request);
		return list;
	}

	

	/*
	 * 
	 * 功能：菜单管理
	 * 作者：曾平
	 * 时间：2019年12月11日 下午8:27:23
	 */
	private void joinTreeNode(Integer parentId, List<TreeObject> list, TreeObject node, HttpServletRequest request) {
		List<SysNaviEntity> result = null;
		if (parentId == null) {
			Condition cond2 = navi.PARENT_ID.isNull();
			result = sysNaviService.select(cond2, navi.ORDERNO.asc());
		} else {
			Condition cond2 = navi.PARENT_ID.eq(parentId);
			result = sysNaviService.select(cond2, navi.ORDERNO.asc());
		}
		for (SysNaviEntity r : result) {
			String id = r.getId();
			String name = r.getName();
			TreeObject treeObject = new TreeObject();
			treeObject.setName(name);
			treeObject.setId(id);
			List<SysNaviEntity> result2 = this.sysNaviService.select(navi.PARENT_ID.eq(Integer.valueOf(id)), navi.ORDERNO.asc());
			if (result2.size() != 0) {
				treeObject.setIsParent(true);
			}
			list.add(treeObject);
		}
	}
	@RequestMapping({ "/getFullNaviTree" })
	public List<TreeObject> getFullNaviTree(Integer pid, HttpServletRequest request) {
		List<TreeObject> list = new ArrayList<>();
		SysUserEntity me = Helper.getMe(request);
		joinFullTreeNode(pid, list,me);
		return list;
	}
	private void joinFullTreeNode(Integer parentId, List<TreeObject> list, SysUserEntity me) {
		List<SysNaviEntity> result = null;
		Condition cond = null;
		if (parentId == null) {
			cond = navi.PARENT_ID.isNull();
		} else {
			cond = navi.PARENT_ID.eq(parentId);
		}
		//cond = cond.and(navi.ID.in(DSL.select(DSL.field("navi_id")).from(DSL.table("sys_org_navi")).where(DSL.field("org_id").eq(me.getOrgId())).asField()));
		result = sysNaviService.select(cond, navi.ORDERNO.asc());
		for (SysNaviEntity r : result) {
			String id = r.getId();
			String name = r.getName();
			TreeObject treeObject = new TreeObject();
			treeObject.setName(name);
			treeObject.setId(id);
			cond = navi.PARENT_ID.eq(Integer.valueOf(id));
			List<TreeObject> children = new ArrayList<>();
			List<SysNaviEntity> result2 = sysNaviService.select(cond, navi.TIER.asc(), this.navi.ORDERNO.asc());
			if (result2.size() != 0) {
				treeObject.setChildren(children);
				treeObject.setIsParent(true);
				joinFullTreeNode(Integer.valueOf(id), children, me);
			}
			list.add(treeObject);
		}
	}
	@RequestMapping({ "/getList" })
	public LayuiTableResponse<SysNaviEntity> getNavis(Integer parentId, Integer limit, Integer page) {
		LayuiTableResponse<SysNaviEntity> ltr = new LayuiTableResponse<>();
		List<SysNaviEntity> list2 = new ArrayList<>();
		Condition cond = navi.PARENT_ID.eq(parentId);
		if (parentId != null) {
			SysNaviEntity entity = sysNaviService.getEntityById(parentId);
			SysDictEntity dic = SysDictService.getFromCaches("valid-state,"+entity.getState());
			entity.setStateTxt(dic==null?"":dic.getName());
			list2.add(entity);
		} else {
			cond = navi.PARENT_ID.isNull();
		}
		Long count = sysNaviService.count(cond);
		PageInfo<SysNaviEntity> pageInfo = new PageInfo<>(limit, page);
		if (parentId==null) {
			ltr.setCount(count);
		} else {
			ltr.setCount(count + 1);
		}
		sysNaviService.select(cond, pageInfo, navi.ORDERNO.asc(),navi.ID.asc());
		List<SysNaviEntity> list = pageInfo.getList();
		
		for (SysNaviEntity nv : list) {
			SysDictEntity dic = SysDictService.getFromCaches("valid-state,"+nv.getState());
			nv.setStateTxt(dic==null?"":dic.getName());
			list2.add(nv);
		}
		ltr.setData(list2);
		return ltr;
	}


	@RequestMapping({ "/getTopNavi" })
	public LayuiTableResponse<SysNaviEntity> getTopNavi(String roleId, HttpServletRequest request) {
		SysUserEntity me = Helper.getMe(request);
		LayuiTableResponse<SysNaviEntity> ltr = new LayuiTableResponse<>();
		ltr.setCode(0);
		if(me==null) {
			ltr.setCode(-1);
			return ltr;
		}
		
		List<SysNaviEntity> list = null;
		if (me.getId().equals("1")) {
			Condition cond2 = navi.PARENT_ID.isNull().and(navi.STATE.eq(5));
			list = sysNaviService.select(cond2, navi.ORDERNO.asc());
		} else {
			Condition cond = navi.PARENT_ID.isNull().and(navi.STATE.eq(5));
			String[] roleCodes = StringUtils.split(me.getRoleCode(),",");
			if(roleCodes.length>0) {
				cond = cond.and(navi.ID.in(DSL.select(SYSROLENAVITB.NAVI_ID).from(SYSROLENAVITB).where(SYSROLENAVITB.ROLE_CODE.in(roleCodes))));
			}else {
				cond = navi.ID.isNull();
			}
			
			list = sysNaviService.select(cond, navi.ORDERNO.asc());
		}
		HashSet<String> set = Sets.newHashSet();// 去重
		for (SysNaviEntity sysnavi : list) {
			set.add(sysnavi.getId());
		}
		list = sysNaviService.select(this.navi.ID.in(set), navi.ORDERNO.asc());
		ltr.setData(list);
		return ltr;
	}

	@RequestMapping({ "/getNaviBar" })
	public LayuiTableResponse<JSONObject> getNaviBar(Integer id) {
		List<JSONObject> data = new ArrayList<>();
		joinNaviBar(id, data, null);
		LayuiTableResponse<JSONObject> ltr = new LayuiTableResponse<JSONObject>();
		ltr.setCount(Long.valueOf(10L));
		ltr.setData(data);
		return ltr;
	}

	private void joinNaviBar(Integer id, List<JSONObject> data, JSONObject node) {
		Record obj = this.sysNaviService.getById(id);
		Integer parentId = (Integer) obj.getValue(this.navi.PARENT_ID);
		JSONObject jobj = new JSONObject();
		jobj.put("name", obj.getValue(this.navi.NAME));
		jobj.put("id", obj.getValue(this.navi.ID));
		jobj.put("parentId", parentId);
		if (parentId!=null) {
			joinNaviBar(parentId, data, null);
		}
		data.add(jobj);
	}

	@RequestMapping({ "/modify" })
	public LayuiTableResponse<SysNaviEntity> modify(SysNaviEntity entity) {
		try {
			SysNaviEntity entity2 = sysNaviService.getEntityById(entity.getId());
			entity.setState(entity2.getState());
			sysNaviService.update(entity);
		} catch (IOException e) {
			e.printStackTrace();
		}
		LayuiTableResponse<SysNaviEntity> ltr = new LayuiTableResponse<>();
		return ltr;
	}


	@RequestMapping({ "/move" })
	public LayuiTableResponse<SysNaviEntity> move(Integer id, Integer parentId) {
		Record record = sysNaviService.getById(id);
		record.set(navi.PARENT_ID, parentId);
		this.sysNaviService.update(record);
		LayuiTableResponse<SysNaviEntity> ltr = new LayuiTableResponse<>();
		return ltr;
	}

	@RequestMapping({ "/setOrderno" })
	public LayuiTableResponse<SysNaviEntity> setOrderno(@RequestParam("ids[]") String[] ids, int direction) {
		for (String id : ids) {
			SysNaviEntity record = this.sysNaviService.getEntityById(id);
			if (record.getOrderno() == null) {
				record.setOrderno(1);
			} else {
				Condition cond = navi.PARENT_ID.eq(Integer.valueOf(record.getParentId()));
				if (record.getParentId() == null) {
					cond = navi.PARENT_ID.isNull();
				}
				if (direction < 0) {
					List<SysNaviEntity> nextNavi = sysNaviService.select(cond.and(navi.ORDERNO.lt(record.getOrderno())),
							navi.ORDERNO.asc());
					if (nextNavi.size() > 0) {
						record.setOrderno(nextNavi.get(0).getOrderno() + direction);
					} else {
						record.setOrderno(record.getOrderno() + direction);
					}
				} else {
					List<SysNaviEntity> nextNavis = sysNaviService
							.select(cond.and(navi.ORDERNO.gt(record.getOrderno())), navi.ORDERNO.asc());

					if (nextNavis.size() > 0) {
						record.setOrderno(nextNavis.get(0).getOrderno() + direction);
					} else {
						record.setOrderno(record.getOrderno() + direction);
					}
				}
			}
			try {
				this.sysNaviService.update(record);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		LayuiTableResponse<SysNaviEntity> ltr = new LayuiTableResponse<>();
		return ltr;
	}

	@RequestMapping({ "/add" })
	public LayuiTableResponse<SysNaviEntity> add(SysNaviEntity entity) {
		this.sysNaviService.insert(entity);
		LayuiTableResponse<SysNaviEntity> ltr = new LayuiTableResponse<>();
		return ltr;
	}

	@RequestMapping({ "/delete" })
	public LayuiTableResponse<SysNaviEntity> delete(@RequestParam("ids[]") Integer[] ids) {
		LayuiTableResponse<SysNaviEntity> ltr = new LayuiTableResponse<>();
		for (Integer id : ids) {
			List<SysNaviEntity> list = this.sysNaviService.select(navi.PARENT_ID.eq(id));
			if (list.size() == 0) {
				this.sysNaviService.deleteById(id);
			}
		}
		return ltr;
	}

	@RequestMapping({ "/abandon" })
	public LayuiTableResponse<SysNaviEntity> abandon(@RequestParam("ids[]") String[] ids) {
		LayuiTableResponse<SysNaviEntity> ltr = new LayuiTableResponse<>();
		
		try {
			for (String id : ids) {
				SysNaviEntity entity = sysNaviService.getEntityById(id);
				entity.setState(11);
				sysNaviService.update(entity);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return ltr;
	}
	@RequestMapping({ "/hide" })
	public LayuiTableResponse<SysNaviEntity> hide(@RequestParam("ids[]") String[] ids) {
		LayuiTableResponse<SysNaviEntity> ltr = new LayuiTableResponse<>();
		
		try {
			for (String id : ids) {
				SysNaviEntity entity = sysNaviService.getEntityById(id);
				entity.setState(7);
				sysNaviService.update(entity);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return ltr;
	}

	@RequestMapping({ "/resume" })
	public LayuiTableResponse<SysNaviEntity> resume(@RequestParam("ids[]") String[] ids) {
		LayuiTableResponse<SysNaviEntity> ltr = new LayuiTableResponse<>();
		try {
			for (String id : ids) {
				SysNaviEntity entity = sysNaviService.getEntityById(id);
				entity.setState(5);
				sysNaviService.update(entity);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return ltr;
	}

	@RequestMapping({ "/getById" })
	public SysNaviEntity getById(String id) {
		SysNaviEntity org = sysNaviService.getEntityById(id);
		return org;
	}

	@RequestMapping({ "/getChildCount" })
	public LayuiTableResponse<SysNaviEntity> getChildCount(Integer id) {
		LayuiTableResponse<SysNaviEntity> ltr = new LayuiTableResponse<>();
		Long count = sysNaviService.count(navi.PARENT_ID.eq(id));
		ltr.setCount(count);
		return ltr;
	}
}
